from django.shortcuts import render
from django.http import HttpResponse
from .tools import *


def experiment3(request):
    return render(request, 'bag_app/experiment3.html')

weights = []
values = []
capacity = None


# 1
def input_parameter(request):
    global weights, values, capacity
    if request.method == 'POST':
        n = int(request.POST.get('n'))
        weights = list(map(eval, request.POST.get('weights').split(",")))
        values = list(map(eval, request.POST.get('values').split(",")))
        capacity = eval(request.POST.get('w'))
        result = input_knapsack_problem(n, weights, values, capacity)
        if "error" not in result:
            result = []
            n, weights, values, capacity = input_knapsack_problem(n, weights, values, capacity)
            for i in range(n):
                result.append({
                    'item': i+1,
                    'weight': weights[i],
                    'value': values[i]
                })
        return render(request, 'bag_app/1.html', {'result': result, 'capacity': capacity})
    return render(request, 'bag_app/1.html')


# 2
def greedy1(request):
    global weights, values, capacity
    if request.method == 'POST':
        time = "时间复杂度：O(nlogn)"
        result = fractional_knapsack(weights, values, capacity)
        return render(request, 'bag_app/2.html', {'result': result, "time": time})
    return render(request, 'bag_app/2.html')


# 3
def greedy2(request):
    global weights, values, capacity
    weights = list(map(int, weights))
    capacity = int(capacity)
    if request.method == 'POST':
        result = knapsack_greedy_01(weights, values, capacity)
        result1 = knapsack_dp(weights, values, capacity)
        return render(request, 'bag_app/3.html', {'result': result, 'result1': result1})
    return render(request, 'bag_app/3.html')


# 4
def bf(request):
    global weights, values, capacity
    weights = list(map(int, weights))
    values = list(map(int, values))
    capacity = int(capacity)
    if request.method == 'POST':
        time = "时间复杂度：O(2^n*n)"
        best_value, best_combination, all_combinations = knapsack_bruteforce(weights, values, capacity)
        best_combination = [[i + 1, weights[i], values[i]] for i in best_combination]
        formatted_combinations = [
            {
                "comb": ', '.join(str(i + 1) for i in comb),  # 物品编号从1开始
                "total_weight": total_weight,
                "total_value": total_value,
                "status": "超载" if total_weight > capacity else "未超载"
            }
            for total_weight, total_value, comb in all_combinations
        ]
        return render(request, 'bag_app/4.html',
                      {"best_value": best_value, "best_combination": best_combination, "combinations": formatted_combinations, 'time': time})
    return render(request, 'bag_app/4.html')


# 5
def dp(request):
    global weights, values, capacity
    weights = list(map(int, weights))
    values = list(map(int, values))
    capacity = int(capacity)
    if request.method == 'POST':
        time = "时间复杂度：O(n*W)"
        result_value, selected_items, table = knapsack_dp1(weights, values, capacity)
        return render(request, 'bag_app/5.html',
                      {"result_value": result_value, "selected_items": selected_items, "table": table, 'time': time})
    return render(request, 'bag_app/5.html')


# 6
def dp_improved(request):
    global weights, values, capacity
    weights = list(map(int, weights))
    values = list(map(int, values))
    capacity = int(capacity)
    if request.method == 'POST':
        dp, max_value, selected_items = knapsack_01(values, weights, capacity)
        return render(request, 'bag_app/6.html',
                      {"result_value": max_value, "selected_items": selected_items, "table": dp})
    return render(request, 'bag_app/6.html')
